//package me.zhengjie.minbearwcs.serivce.mission.storageProcessor.booking.Floor3Or4.impl;
//
//import lombok.RequiredArgsConstructor;
//import lombok.extern.slf4j.Slf4j;
//import org.springframework.stereotype.Component;
//import me.zhengjie.minbearwcs.dao.lift.inf.LiftRequestPointGroupDao;
//import me.zhengjie.minbearwcs.dao.stock.inf.MaterialStockDao;
//import me.zhengjie.minbearwcs.dao.storage.inf.DualHeadStorageDao;
//import me.zhengjie.minbearwcs.dao.storage.inf.DualHeadStorageGroupDao;
//import me.zhengjie.minbearwcs.dao.storage.inf.NormalStorageDao;
//import me.zhengjie.minbearwcs.entity.DTO.inboundOld.mission.InboundMissionPoint;
//import me.zhengjie.minbearwcs.entity.DTO.transfer.Tuple;
//import me.zhengjie.minbearwcs.entity.PO.wcs.storage.dualHeadStorage.DualHeadStorage;
//import me.zhengjie.minbearwcs.entity.PO.wcs.storage.dualHeadStorage.type.DualStorageType;
//import me.zhengjie.minbearwcs.serivce.mission.storageProcessor.booking.Floor3Or4.Storage3Or4FloorBookingSelector;
//
//import java.util.Comparator;
//import java.util.List;
//import java.util.Map;
//import java.util.stream.Collectors;
//
//@Slf4j
//@Component
//@RequiredArgsConstructor
//public class SortStorage3Or4FloorByProductLine implements Storage3Or4FloorBookingSelector {
//
//    private final MaterialStockDao materialStockDao;
//    private final DualHeadStorageGroupDao dualHeadStorageGroupDao;
//    private final DualHeadStorageDao dualHeadStorageDao;
//    private final NormalStorageDao normalStorageDao;
//    private final LiftRequestPointGroupDao liftRequestPointGroupDao;
//
//    @Override
//    public synchronized Tuple<InboundMissionPoint> searchAndBooking(String palletCode, String startPoint) {
//        String productionLine = materialStockDao.selectProductionLineByPallet(palletCode);
//        if (productionLine == null) {
//            log.info("无法找到栈板 {} 对应的生产线", palletCode);
//            return Tuple.tuple(null, false);
//        }
//
//        List<String> dualHeadStorageGroups = dualHeadStorageGroupDao.selectGroupNamesByStorageTypeAndProductionLine(DualStorageType.Floor3Or4DualStorage, productionLine);
//
//        for (String groupName : dualHeadStorageGroups) {
//            List<DualHeadStorage> dualHeadStorageList = dualHeadStorageDao.selectByDualHeadStorageGroupCode(groupName);
//            Map<Integer, List<DualHeadStorage>> collect = dualHeadStorageList.stream()
//                    .collect(Collectors.groupingBy(DualHeadStorage::getRowNum));
//            for (List<DualHeadStorage> value : collect.values()) {
//                value.sort(Comparator.comparingInt(DualHeadStorage::getColumnNum));
//                // TODO : 暂时使用双头双通方案，有需要再加上单头单通
//                return findDualEntranceBooking(value, palletCode, startPoint);
//            }
//
//        }
//
//        return Tuple.tuple(null, false);
//    }
//
//
//    // 双出口
//    private Tuple<InboundMissionPoint> findDualEntranceBooking(List<DualHeadStorage> value, String palletCode, String startPoint) {
//        int size = value.size();
//        if (size == 0) return Tuple.tuple(null, false);
//
//        int midSize = size / 2 - 1;
//        for (int i = midSize; i >= 0; i--) {
//            Tuple<InboundMissionPoint> res = dualEntrancejudgeAndBook(value, i, palletCode, startPoint);
//            if (res.success) {
//                return res;
//            }
//        }
//
//        for (int i = midSize + 1; i < size; i++) {
//            Tuple<InboundMissionPoint> res = dualEntrancejudgeAndBook(value, i, palletCode, startPoint);
//            if (res.success) {
//                return res;
//            }
//        }
//
//        return Tuple.tuple(null, false);
//
//
//    }
//
//    private int statEntrance(DualHeadStorage bookingStorage, int nowNum) {
//        if (bookingStorage.getIsEntrance() == 1) {
//            return nowNum + 1;
//        }
//        return nowNum;
//    }
//
//    private boolean judgeCanPass(DualHeadStorage bookingStorage) {
//        return bookingStorage.getEnable() == 1 &&
//                bookingStorage.getBookingPalletCode() == null &&
//                bookingStorage.getPalletCode() == null;
//    }
//
//    private Tuple<InboundMissionPoint> book(DualHeadStorage dualHeadStorage, String palletCode, String startPoint) {
//        dualHeadStorageDao.updateBookingPalletById(dualHeadStorage.getId(), palletCode);
//        String liftGroup = normalStorageDao.selectLiftRequestGroupByQrCode(startPoint);
//        String requestLiftPoint = liftRequestPointGroupDao.selectRequestPointByGroupCode(liftGroup);
//        InboundMissionPoint inboundMissionPoint = new InboundMissionPoint(null,
//                dualHeadStorage.getQrPoint(),
//                requestLiftPoint);
//        return Tuple.tuple(inboundMissionPoint, true);
//    }
//
//    private Tuple<InboundMissionPoint> dualEntrancejudgeAndBook(List<DualHeadStorage> value, int i, String palletCode, String startPoint) {
//        int size = value.size();
//        DualHeadStorage bookingStorage = value.get(i);
//        boolean leftJudge = true;
//        int leftEntranceNum = 0;
//        for (int j = i - 1; j >= 0; j--) {
//            DualHeadStorage storage = value.get(j);
//            leftEntranceNum = statEntrance(storage, leftEntranceNum);
//            boolean canPass = judgeCanPass(storage);
//            leftJudge = leftJudge && canPass;
//            if (!canPass) {
//                break;
//            }
//        }
//        if (leftJudge && leftEntranceNum > 0) {
//            return book(bookingStorage, palletCode, startPoint);
//        }
//
//        boolean rightJudge = true;
//        int rightEntranceNum = 0;
//        for (int k = i + 1; k < size; k++) {
//            DualHeadStorage storage = value.get(k);
//            rightEntranceNum = statEntrance(storage, rightEntranceNum);
//            boolean canPass = judgeCanPass(storage);
//            rightJudge = rightJudge && canPass;
//            if (!canPass) {
//                break;
//            }
//        }
//
//        if (rightJudge && rightEntranceNum > 0) {
//            return book(bookingStorage, palletCode, startPoint);
//        }
//
//        return Tuple.tuple(null, false);
//    }
//
//
//    @Override
//    public Tuple<String> finishAndClearBook(String point) {
//        boolean res = dualHeadStorageDao.updateBookingPalletByQrPoint(point, null);
//        if (res) {
//            log.info("3/4F点位：{}，预定栈板清除成功", point);
//        }
//        return Tuple.tuple("", res);
//    }
//
//}
